/**************************************************************************//**
 * @file    main.c
 * @author  İsmail SEZEN (email: sezenismail@gmail.com)
 * @date    06.02.2011
 *
 * <b>Description</b>
 *
 * Main module of siklon project. Most of the job done here.\n
 *
 * Copyright (C) 2009 İsmail SEZEN
 *
 * <b>License</b>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *****************************************************************************/

/* Include Directives *///{
//#define _GNU_SOURCE
//#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
//#include <unistd.h>
#include <StringHelper.h>
#include <csv_parser.h>
#include <FileHelpers.h>
#include <logger.h>
#include "siklon/Siklon.h"
#include "version.h"
//}

/* Variables *///{
/*! \brief Name of the project */
static const char* _progname = "siklon";
/*! \brief Copyright Notice */
static const char* _copy = "Copyright (C) 2009  Ismail SEZEN";
/*! \brief Name/paths of the NC file to be read */
static char* _inputFilePath;
/*! \brief Name/path of the output file */
static char* _outputFilePath;
/*! \brief Name/path of the error file */
static char* _errorFilePath;
/*! \brief Exit status Code */
static int _exitStatus = EXIT_FAILURE;
static int _DetectionType = 0;
static int _ExactPoint = 0;
static int _showInfo = 0;
//
static float lat_start=0,lat_end=0,lon_start=0,lon_end=0;
static int time_start=-1, time_end=-1,time_step=-1;
static int level=0;
//}

/* Function Prototypes *///{
static void projectInfo(void);
static void usage(void);
static int decodeCommandLine( int argc,char* const*	argv);
static int isNCFile(char* fileName);
//}

/*!
 * \brief Main Entry Point
 *
 * This is the main entry poin for the program
 *
 * @param argc is arguments count
 * @param *argv[] are the arguments array
 *
 * \return Returns an integer value indicates the \ref _exitStatus "exit status"
 */
int main(int argc, char *argv[]) {
	projectInfo();
	if (decodeCommandLine(argc, argv)) {
		//log_debug("%s %s %s",_inputFilePath,_outputFilePath,_errorFilePath);
		FILE* fout = fh_redirectstdoutToFile(_outputFilePath);
		FILE* ferr = fh_redirectstderrToFile(_errorFilePath);

		if(isNCFile(_inputFilePath)) {//if input is NC File
			if(_showInfo) {
				sk_print_file_info(_inputFilePath);
			} else {
				sk_Init(_inputFilePath, lat_start, lat_end, lon_start, lon_end, time_start, time_end, time_step, level);
				sk_printInitialConditions();
				sk_scan();
				sk_finalize();
			}
		}else {//CSV File.
			csv_read_file(_inputFilePath,';');//Read and parse it.
			register int i =0;
			for(i=0;i<csv_rowCount;i++) printf("%d) %s %s %s\n",i,csv_data[i][0],csv_data[i][1],csv_data[i][2]);
			printf("%d\n",csv_rowCount);
			csv_finalize();
			//printf("%s",csv_data[0][0]);
			//char	_ncFile[] = "hgt." + csv_data[0][0] + ".nc";
		}
		fh_close(fout);
		fh_close(ferr);
	}

	log_debug_close
	return _exitStatus;
}

/** Function : isNCFile
 * @param *fileName File name to check
 * Checks the file extension is nc or csv*/

/*!
 * \brief Checks the file extension is nc or csv
 *
 * @sa fh_checkFileExtension
 *
 * @param fileName File name to check
 *
 * \return Returns an integer value indicates the \ref _exitStatus "exit status"
 */
static int isNCFile(char* fileName) {
	return fh_checkFileExtension(fileName,"nc");
}

static void setTime(int start,int end, int step){
	time_start = start;
	time_end = end;
	time_step = step;
}

static int setTimeProperties(int field_count, char** p,const int field_count_limit) {
	if( field_count > 0 ) {
		if(field_count > field_count_limit) field_count = field_count_limit;
		switch(field_count){
			case 3:
			setTime(atoi(p[0]),atoi(p[1]),atoi(p[2]));
			break;
			case 2:
			setTime(atoi(p[0]),atoi(p[1]),1);
			break;
			case 1:
			setTime(atoi(p[0]),atoi(p[0]),1);
			break;
		}
		optind++;
	}
	return field_count;
}

static int setDomProperties(int field_count, char** p,const int field_count_limit) {
	if( field_count > 0 ) {
		if(field_count > field_count_limit) field_count = field_count_limit;
		switch(field_count) {
			case 4:
			lon_end = atof(p[3]);
			case 3:
			lon_start = atof(p[2]);
			case 2:
			lat_end = atof(p[1]);
			case 1:
			lat_start = atof(p[0]);
			break;
		}
		optind++;
	}
	return field_count;
}

static int getProperties(int argc, char* const*	argv) {
	char * prop = NULL;
	do {
		prop = optind < argc ? argv[optind] : NULL;
		if(prop != NULL) {
			int field_count = 0;
			char** p2 = NULL;
			char** p = NULL;
			field_count = sh_splitString2(prop, 15, ':',&p);
			if(field_count>1) {
				if( strcmp(p[0], "dom")==0 ) {
					field_count = sh_splitString2(p[1], 4, ',',&p2);
					if( !setDomProperties(field_count, p2, 4) ) {
						printf("Error in dom: property params!");
						free(p);
						exit(EXIT_FAILURE);
					}
				}else if( strcmp(p[0], "time")==0 ) {
					field_count = sh_splitString2(p[1], 4, ',', &p2);
					if(!setTimeProperties(field_count, p2, 3)) {
						printf("Error in time: property params!");
						free(p);
						exit(EXIT_FAILURE);
					}
				}else if( strcmp(p[0], "lev")==0 ) {
					level = atoi(p[1]);
					optind++;
				}
				if(p2!=NULL) free(p2);
			}else {
				prop = NULL;
			}
			if(p!=NULL) free(p);
		}
	}while(prop != NULL);
	return optind;
}

/** Function : decodeCommandLine
 * @param argc is arguments count
 * @param *argv[] are the arguments array
 * Command Line decode function */
static int decodeCommandLine(int argc, char* const*	argv) {
    int c;
    int success = 0;
    if(argc == 1){
    	(void)fprintf(stderr, "Type <%s -h> for usage information.\n", _progname);
    	return success;
    }
    while ((c = getopt(argc, argv, "CAeih")) != -1) {
		switch (c) {
			case 'C'://Cyclone Detection
			_DetectionType = 0;
			printf("_DetectionType = 0\n");
			continue;
			case 'A'://Anticyclone Detection
			_DetectionType = 1;
			printf("_DetectionType = 1\n");
			continue;
			case 'e'://Exact Point Detection
			_ExactPoint = 1;
			printf("_ExactPoint = 1\n");
			continue;
			case 'i'://Exact Point Detection
			_showInfo = 1;
			printf("_ExactPoint = 1\n");
			continue;
			case 'h'://Print Usage
			/*FALLTHROUGH*/
			case '?':
			usage();
			break;
			default:
			(void)fprintf(stderr, "%s: Unknown option \"%c\"\n", _progname,  c);
			usage();
		}
		break;
    }

	if (c == -1) {
		getProperties(argc,argv);
		_inputFilePath = optind < argc ? argv[optind] : NULL;
		optind++;
		_outputFilePath = optind < argc ? argv[optind] : NULL;
		optind++;
		_errorFilePath = optind < argc ? argv[optind] : NULL;
		success = 1;
    }
    return success;
}

/** Function : usage
 * Prints the usage information to standart error */
static void usage(void) {
    (void)fprintf(stderr,
	"Usage: %s [-C|-A] [-hei] [dom:lat_start, lat_end, lon_start, lon_end | time: start, end, step | lev:level] Input_file [Output_file] \n"
	"\n"
	"where:\n"
	"    -C            Find cyclone points.\n"
	"    -A            Find anticyclone points.\n"
	"    -h            Help. Print this message.\n"
	"    -e            exact points.\n"
	"    -i            show file info.\n"
	"    Input_file    Input CSV File or .nc data file.\n"
	"    [Output_file] Output File.\n\n"
	"Initial Conditions:\n"
	"    dom:          set domain properties.\n"
	"      lat_start   Start value of latitude (float).\n"
	"      lat_end     End value of latitude (float).\n"
	"      lon_start   Start value of longtitude (float).\n"
	"      lon_end     End value of longtitude (float).\n"
	"    time:         set time properties.\n"
	"      time_start  Start value of latitude (integer).\n"
	"      time_end    End value of latitude (integer).\n"
	"      time_step   Time step (integer).\n"
	"    lev:          set level properties.\n"
	"      level       level index to scan.\n",
	_progname);
}

/** Function : projectInfo
 * PRints the project info on the screen */
static void projectInfo(void){
	char* warning = "This program comes with ABSOLUTELY NO WARRANTY;\nThis is free software, and you are welcome to redistribute it.\nunder certain conditions";
	 (void)fprintf(stderr,
	 "%s v%s%s\n"
	 "Date: %s.%s.%s\n"
	 "%s\n"
	 "%s\n\n",
	 _progname, FULLVERSION_STRING, STATUS_SHORT,
	DATE, MONTH, YEAR,
	 _copy,
	 warning);
}
